#include "delegate.h"
#include"sourcemanage.h"
#include <QCheckBox>
#include <QApplication>
#include<QMouseEvent>

//SpinBoxDelegate
SpinBoxDelegate::SpinBoxDelegate(QObject *parent)
    :  QStyledItemDelegate(parent)
{

}

QWidget *SpinBoxDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &,
    const QModelIndex &) const
{
    QSpinBox *editor = new QSpinBox(parent);
    editor->setMinimum(0);
    editor->setMaximum(100);

    return editor;
}

void SpinBoxDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    int value = index.model()->data(index, Qt::EditRole).toInt();

    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->setValue(value);
}

void SpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QSpinBox *spinBox = static_cast<QSpinBox*>(editor);
    spinBox->interpretText();
    int value = spinBox->value();

    model->setData(index, value, Qt::EditRole);
}

//QDoubleSpinBox
DoubleSpinBoxDelegate::DoubleSpinBoxDelegate(QObject *parent)
    :  QStyledItemDelegate(parent)
{

}

QWidget *DoubleSpinBoxDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &,
    const QModelIndex &) const
{
    QDoubleSpinBox *editor = new QDoubleSpinBox(parent);
    //editor->setMinimum(0);
    //editor->setMaximum(100);
    editor->setDecimals(5);
    return editor;
}
//
void DoubleSpinBoxDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    double value = index.model()->data(index, Qt::EditRole).toDouble();

    QDoubleSpinBox *spinBox = static_cast<QDoubleSpinBox*>(editor);
    spinBox->setValue(value);
}

void DoubleSpinBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QDoubleSpinBox *spinBox = static_cast<QDoubleSpinBox*>(editor);
    spinBox->interpretText();
    double value = spinBox->value();

    model->setData(index, value, Qt::EditRole);
}

//LineEditDelegate
LineEditDelegate::LineEditDelegate(QObject *parent,int style)
    :  QStyledItemDelegate(parent)
{
    this->style=style;
}

QWidget *LineEditDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &,
    const QModelIndex &index) const
{
    QLineEdit *editor = new QLineEdit(parent);
    //editor->setStyleSheet("max-height:1024px;");
    //QRegExp regExp;

    switch(style)
    {
        case 0:
            editor->setValidator(new QDoubleValidator(0,100,2,parent));
            break;
        case 1:
            editor->setValidator(new QDoubleValidator(0,10000,5,parent));
            break;
        case 2:
            editor->setValidator(new QDoubleValidator(parent));
            break;
        case 3:
            editor->setValidator(new QIntValidator(0,100,parent));
            break;
        case 4:
            editor->setValidator(new QIntValidator(parent));
            break;
        case 5:
            break;
    }
    return editor;
}

void LineEditDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    QString value= index.model()->data(index, Qt::DisplayRole).toString();

    QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
    lineEdit->setText(value);
}

void LineEditDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QLineEdit *lineEdit = static_cast<QLineEdit*>(editor);
    QString value = lineEdit->text();
    model->setData(index, value, Qt::EditRole);
}

//ComboxDelegate
ComboxDelegate::ComboxDelegate(QObject *parent,int style,Experiment *pExperiment)
    :  QStyledItemDelegate(parent)
{
    this->style=style;
    this->pExperiment=pExperiment;
}

QWidget *ComboxDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &,
    const QModelIndex &index) const
{
    QComboBox *editor = new QComboBox(parent);
    //editor->setStyleSheet("max-height:1024px;");

    QStringList strs;
    switch(style)
    {
    case 0://
        editor->addItems(SM->options.value("ResolutionType"));
        break;
    case 1://
        if(pExperiment!=NULL)
        {
            strs=pExperiment->GetQuantitativeElement(0).values();
        }
        editor->addItems(SM->options.value("InternalSType")+strs);
        break;
    case 2://
        editor->addItems(SM->options.value("UnitType"));
        break;
    case 3:
        editor->addItems(SM->options.value("QuantitativeType"));
        break;
    case 4:
        switch(index.column())
        {
        case 1:
            editor->addItems(SM->options.value("FittingTimesType"));
            break;
        case 2:
            editor->addItems(SM->options.value("WeightType1"));
            break;
        }
        break;
    case 5:
        editor->addItems(SM->options.value("WeightType2"));
        break;
    case 6:
        switch(index.column())
        {
        case 2:
            editor->addItems(SM->options.value("SampleType"));
            break;
        case 3:
            editor->addItems(SM->options.value("QcType"));
            break;
        }
        break;
    case 7:
        editor->addItems(SM->options.value("StateType"));
        break;
    case 8:
        editor->addItems(SM->options.value("OnOffType"));
        break;
    case 9:
        editor->addItems(SM->options.value("DirectType"));
        break;
    case 10:
        editor->addItems(SM->GetWorkFlow().GetFlowNames());
        break;
        /*
    case 7:
        switch(index.column())
        {
        case 2:
            editor->addItems(SM->options.value("SampleType"));
            break;
        case 3:
            editor->addItems(SM->options.value("SampleType"));
            break;
        }
        break;
        */
    }
    return editor;
}

void ComboxDelegate::setEditorData(QWidget *editor,
                                    const QModelIndex &index) const
{
    QString value = index.model()->data(index, Qt::EditRole).toString();

    QComboBox *combox = static_cast<QComboBox*>(editor);
    int  index1 = combox->findText(value);
    combox->setCurrentIndex(index1);
}

void ComboxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
    QComboBox *combox = static_cast<QComboBox*>(editor);
    QString value = combox->currentText();
    model->setData(index, value, Qt::DisplayRole);
    //model->setData(index,combox->itemData(combox->currentIndex(),Qt::DecorationRole),Qt::DecorationRole);
}

/*
void ComboxDelegate::updateEditorGeometry(QWidget *editor,
    const QStyleOptionViewItem &option, const QModelIndex &) const
{
    editor->setGeometry(option.rect);
}
*/

CheckBox::CheckBox(QObject *parent,int style)
    :  QStyledItemDelegate(parent)
{
    this->style=style;
}

void CheckBox::paint(QPainter *painter, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
{
    QPixmap pixmap;
    switch(this->style)
    {
    case 0:
        //if ((index.column() == 0)||(index.column()==1))
          {
            //if((index.column()==0)) return;
              //获取值
              int checked = index.model()->data(index).toInt();
              //按钮的风格选项
                QStyleOptionButton checkBoxOption;
                checkBoxOption.palette=option.palette;
                checkBoxOption.state =option.state;
              //根据值判断是否选中
              if(checked==1)
              {
                  checkBoxOption.state |= QStyle::State_On;
              }
              else if(checked==0)
              {
                  checkBoxOption.state |= QStyle::State_Off;
              }
              else//
              {
                checkBoxOption.state |= QStyle::State_NoChange;
              }

              //返回QCheckBox几何形状
              checkBoxOption.rect = CheckBoxRect(option);

              QApplication::style()->drawControl(QStyle::CE_CheckBox,&checkBoxOption,painter);
          }
          //else
          {
            //否则调用默认委托
           // QStyledItemDelegate::paint(painter, option, index);
          }
          break;
    case 1:
        //if ((index.column() == 0)||(index.column()==1))
          {
            //if((index.column()==0)) return;
              //获取值
              int checked = index.model()->data(index).toInt();
              //按钮的风格选项
                QStyleOptionButton checkBoxOption;
                checkBoxOption.palette=option.palette;
                checkBoxOption.state =option.state;
              //根据值判断是否选中
              if(checked==1)
              {
                  checkBoxOption.state |= QStyle::State_On;
              }
              else if(checked==0)
              {
                  checkBoxOption.state |= QStyle::State_Off;
              }
              else//
              {
                  break;
                  checkBoxOption.state |= QStyle::State_NoChange;
              }

              //返回QCheckBox几何形状
              checkBoxOption.rect = CheckBoxRect(option);

              QApplication::style()->drawControl(QStyle::CE_CheckBox,&checkBoxOption,painter);
          }
          //else
          {
            //否则调用默认委托
           // QStyledItemDelegate::paint(painter, option, index);
          }
          break;
      default:
          break;
    }
}



QRect CheckBox::CheckBoxRect(const QStyleOptionViewItem &viewItemStyleOptions) const
{
    //绘制按钮所需要的参数
    QStyleOptionButton checkBoxStyleOption;
    //按照给定的风格参数 返回元素子区域

    QRect checkBoxRect = QApplication::style()->subElementRect( QStyle::SE_CheckBoxIndicator, &checkBoxStyleOption);
    //返回QCheckBox坐标

    QPoint checkBoxPoint(viewItemStyleOptions.rect.x() + viewItemStyleOptions.rect.width() / 2 - checkBoxRect.width() / 2,
                         viewItemStyleOptions.rect.y() + viewItemStyleOptions.rect.height() / 2 - checkBoxRect.height() / 2);
    return QRect(checkBoxPoint, checkBoxRect.size());

/*
    QPoint checkBoxPoint1(viewItemStyleOptions.rect.x() + viewItemStyleOptions.rect.width() / 4 ,
                         viewItemStyleOptions.rect.y() + viewItemStyleOptions.rect.height() / 4 );
    QPoint checkBoxPoint2(viewItemStyleOptions.rect.x() + viewItemStyleOptions.rect.width() *3/ 4 ,
                         viewItemStyleOptions.rect.y() + viewItemStyleOptions.rect.height() *3/ 4 );
    //返回QCheckBox几何形状
    return QRect(checkBoxPoint1, checkBoxPoint2);
    */

}

bool CheckBox::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,  const QModelIndex &index)
{
    if (event->type() == QEvent::MouseButtonPress)
    {
        QMouseEvent* e =(QMouseEvent*)event;
        if(index.flags()&Qt::ItemIsEnabled!=Qt::ItemIsEnabled) return false;

        int checked = model->data(index).toInt();
        switch(style)
        {
        case 0:
            if(option.rect.contains(e->x(), e->y()))
            //if(CheckBoxRect(option).contains(e->x(), e->y()))
            {
                if(checked==2)
                {
                    model->setData(index, 0);//2
                }
                else if(checked==0)
                {
                    model->setData(index, 1);//
                }
                else //=1
                {
                   model->setData(index, 0);
                }

            }
            break;
        case 1://
            {
                SystemState systemState=SM->GetSystemState();
                if(systemState.START_STOP==1) return false;

                if(option.rect.contains(e->x(), e->y()))
                //if(CheckBoxRect(option).contains(e->x(), e->y()))
                {
                    if(checked==1)
                    {
                        model->setData(index, 0);//2
                    }
                    else if(checked==0)
                    {
                        model->setData(index, 1);//
                    }
                }
            }
            break;
        default:
            break;
        }
        return false;
    }

    //if (event->type() == QEvent::MouseButtonRelease) {
    //    QMouseEvent* e =(QMouseEvent*)event;
   // }
    if (event->type() == QEvent::MouseButtonDblClick)
    {
        QMouseEvent* e =(QMouseEvent*)event;
    }
    return false;
}

